package co.fitstart.entity.user.agent;

import java.beans.Transient;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;

import com.demo2do.core.format.DecimalFormat;
import com.demo2do.core.format.PersistentFormat;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;

import co.fitstart.entity.order.Order;
import co.fitstart.entity.user.User;

@Entity
@Table(name = "agent")
@PersistentFormat
@JsonIgnoreProperties(value={"hibernate_lazy_initializer","handler","fieldHandler"})
public class Agent {
    
    @Id
    @GeneratedValue
    private Long id;
    
    private String name;
    
    private String mobile;
    
    /** 腾讯字段: 用户的标识，对当前公众号唯一 */
    private String openid;
    
    /** 结算账号 */
    private String account;
    
    /** 真实姓名 */
    private String realName;
    
    /** 微信号 */
    private String webchatId;
    
    /** 总回扣 */
    @DecimalFormat(scale = 100)
    private int kickbackTotal;
    
    /** 待提现金额 */
    @DecimalFormat
    private int withdrawingTotal;
    
    /** 已提现金额 */
    @DecimalFormat
    private int withdrawedTotal;
    
    /** 总折扣金额 */
    @DecimalFormat(scale = 100)
    private int discountTotal;
    
    /** 总购买人数 */
    private int purchaserTotal;
    
    @Column(name = "is_disabled")
    private boolean disabled;
    
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @PersistentFormat
    @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
    @JsonIdentityReference(alwaysAsId=true)
    private User user;
    
    /**
     * The default constructor
     */
    public Agent() {
        
    }
    
    /**
     * 
     * @param user
     */
    public Agent(User user) {
        this.name = user.getName();
        this.mobile = user.getMobile();
        this.openid = user.getOpenid();
        this.user = user;
        this.disabled = false;
    }
    
    /**
     * 
     * @return
     */
    public Agent disable() {
        this.disabled = true;
        return this;
    }
    
    /**
     * 
     * @return
     */
    public Map<String, Object> describe() {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("typeDescription", this.getAccountTypeDescription());
        parameters.put("accountType", this.getAccountType());
        parameters.put("account", account);
        parameters.put("realName", realName);
        parameters.put("webchatId", webchatId);
        
        return parameters;
    }
    
    /**
     * 
     * @return
     */
    public Map<String, Object> withdrawDescribe() {
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("kickbackTotal", kickbackTotal == 0 ? "0.00" : new BigDecimal(kickbackTotal).divide(new BigDecimal(100)));
        parameters.put("couldWithdraw", kickbackTotal - withdrawingTotal == 0 ? "0.00" : new BigDecimal(kickbackTotal - withdrawingTotal).divide(new BigDecimal(100)));
        return parameters;
    }
    
    /**
     * 
     * @param account
     * @param realName
     * @param webchatId
     * @return
     */
    public Agent editAccount(String account, String realName) {
        this.account = account;
        this.realName = realName;
    	return this;
    }
    
    /**
     * 
     * @param order
     * @param agentDiscount
     * @return
     */
    public Agent consume(Order order, AgentDiscount agentDiscount) {
    	this.purchaserTotal = this.purchaserTotal + 1;
    	this.discountTotal = this.discountTotal + (order.discount(agentDiscount));
    	this.kickbackTotal = this.kickbackTotal + (order.getCommission());
    	
    	return this;
    }
    
    /**
     * 
     * @param offer
     * @return
     */
    public Agent withdraw(int offer) {
        this.withdrawingTotal = this.withdrawingTotal + offer;
        return this;
    }
    
    /**
     * 
     * @param offer
     * @return
     */
    public Agent pay(int offer) {
        this.kickbackTotal = this.kickbackTotal - offer;
        this.withdrawingTotal = this.withdrawingTotal - offer;
        this.withdrawedTotal = this.withdrawedTotal + offer;
        return this;
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public BigDecimal getDecimalKickbackTotal() {
        return new BigDecimal(kickbackTotal).divide(new BigDecimal(100));
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public BigDecimal getDecimalWithdrawingTotal() {
        return new BigDecimal(withdrawingTotal).divide(new BigDecimal(100));
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public BigDecimal getDecimalWithdrawedTotal() {
        return new BigDecimal(withdrawedTotal).divide(new BigDecimal(100));
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public String getAccountType() {
        String accountType = "";
        if(StringUtils.isEmpty(account) && StringUtils.isEmpty(realName)) {
            accountType = "wechat";
        } else if (StringUtils.isEmpty(webchatId)) {
            accountType = "alipay";
        }
        return accountType;
    }
    
    /**
     * 
     * @return
     */
    @Transient
    public String getAccountTypeDescription() {
        String accountType = "";
        if(StringUtils.isEmpty(account) && StringUtils.isEmpty(realName)) {
            accountType = "微信";
        } else if (StringUtils.isEmpty(webchatId)) {
            accountType = "支付宝";
        }
        return accountType;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the mobile
     */
    public String getMobile() {
        return mobile;
    }

    /**
     * @return the openid
     */
    public String getOpenid() {
        return openid;
    }

    /**
     * @return the account
     */
    public String getAccount() {
        return account;
    }

    /**
     * @return the realName
     */
    public String getRealName() {
        return realName;
    }

    /**
     * @return the webchatId
     */
    public String getWebchatId() {
        return webchatId;
    }

    /**
     * @return the kickbackTotal
     */
    public int getKickbackTotal() {
        return kickbackTotal;
    }

    /**
     * @return the withdrawingTotal
     */
    public int getWithdrawingTotal() {
        return withdrawingTotal;
    }

    /**
     * @return the withdrawedTotal
     */
    public int getWithdrawedTotal() {
        return withdrawedTotal;
    }

    /**
     * @return the discountTotal
     */
    public int getDiscountTotal() {
        return discountTotal;
    }

    /**
     * @return the purchaserTotal
     */
    public int getPurchaserTotal() {
        return purchaserTotal;
    }

    /**
     * @return the disabled
     */
    public boolean isDisabled() {
        return disabled;
    }

    /**
     * @return the user
     */
    public User getUser() {
        return user;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param mobile the mobile to set
     */
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    /**
     * @param openid the openid to set
     */
    public void setOpenid(String openid) {
        this.openid = openid;
    }

    /**
     * @param account the account to set
     */
    public void setAccount(String account) {
        this.account = account;
    }

    /**
     * @param realName the realName to set
     */
    public void setRealName(String realName) {
        this.realName = realName;
    }

    /**
     * @param webchatId the webchatId to set
     */
    public void setWebchatId(String webchatId) {
        this.webchatId = webchatId;
    }

    /**
     * @param kickbackTotal the kickbackTotal to set
     */
    public void setKickbackTotal(int kickbackTotal) {
        this.kickbackTotal = kickbackTotal;
    }

    /**
     * @param withdrawingTotal the withdrawingTotal to set
     */
    public void setWithdrawingTotal(int withdrawingTotal) {
        this.withdrawingTotal = withdrawingTotal;
    }

    /**
     * @param withdrawedTotal the withdrawedTotal to set
     */
    public void setWithdrawedTotal(int withdrawedTotal) {
        this.withdrawedTotal = withdrawedTotal;
    }

    /**
     * @param discountTotal the discountTotal to set
     */
    public void setDiscountTotal(int discountTotal) {
        this.discountTotal = discountTotal;
    }

    /**
     * @param purchaserTotal the purchaserTotal to set
     */
    public void setPurchaserTotal(int purchaserTotal) {
        this.purchaserTotal = purchaserTotal;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    /**
     * @param user the user to set
     */
    public void setUser(User user) {
        this.user = user;
    }
    
}
